Add MOVSX instr support to VMX MMIO decoder.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 11 Nov 2005 09:41:25 +0000 (10:41 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 11 Nov 2005 09:41:25 +0000 (10:41 +0100)
Signed-off-by: Xin Li <xin.b.li@intel.com>
xen/arch/x86/vmx_io.c
xen/arch/x86/vmx_platform.c
xen/arch/x86/vmx_vlapic.c
xen/include/asm-x86/vmx_platform.h

index 5b879bd52e2c26092f53e8804b9e6e98871cd9c6..7cbdafb277054c09636ffbf8da080d0abc31d63f 100644 (file)
@@ -459,14 +459,56 @@ static void vmx_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p,
         }
         break;
 
-    case INSTR_MOVZ:
+    case INSTR_MOVZX:
         if (dst & REGISTER) {
+            switch (size) {
+            case BYTE:
+                p->u.data &= 0xFFULL;
+                break;
+
+            case WORD:
+                p->u.data &= 0xFFFFULL;
+                break;
+
+            case LONG:
+                p->u.data &= 0xFFFFFFFFULL;
+                break;
+
+            default:
+                printk("Impossible source operand size of movzx instr: %d\n", size);
+                domain_crash_synchronous();
+            }
             index = operand_index(dst);
+            set_reg_value(operand_size(dst), index, 0, regs, p->u.data);
+        }
+        break;
+
+    case INSTR_MOVSX:
+        if (dst & REGISTER) {
             switch (size) {
-            case BYTE: p->u.data = p->u.data & 0xFFULL; break;
-            case WORD: p->u.data = p->u.data & 0xFFFFULL; break;
-            case LONG: p->u.data = p->u.data & 0xFFFFFFFFULL; break;
+            case BYTE:
+                p->u.data &= 0xFFULL;
+                if ( p->u.data & 0x80ULL )
+                    p->u.data |= 0xFFFFFFFFFFFFFF00ULL;
+                break;
+
+            case WORD:
+                p->u.data &= 0xFFFFULL;
+                if ( p->u.data & 0x8000ULL )
+                    p->u.data |= 0xFFFFFFFFFFFF0000ULL;
+                break;
+
+            case LONG:
+                p->u.data &= 0xFFFFFFFFULL;
+                if ( p->u.data & 0x80000000ULL )
+                    p->u.data |= 0xFFFFFFFF00000000ULL;
+                break;
+
+            default:
+                printk("Impossible source operand size of movsx instr: %d\n", size);
+                domain_crash_synchronous();
             }
+            index = operand_index(dst);
             set_reg_value(operand_size(dst), index, 0, regs, p->u.data);
         }
         break;
index 386ac55e40c634c852ac2d2b2148ebac6046ad7f..2ee14c65eca61c6832dc5e155fb63d857405f204 100644 (file)
@@ -581,25 +581,39 @@ static int vmx_decode(int vm86, unsigned char *opcode, struct instruction *instr
     }
 
     switch (*++opcode) {
-    case 0xB6: /* movz m8, r16/r32 */
-        instr->instr = INSTR_MOVZ;
+    case 0xB6: /* movzx m8, r16/r32/r64 */
+        instr->instr = INSTR_MOVZX;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         index = get_index(opcode + 1, rex);
         instr->operand[0] = mk_operand(BYTE, 0, 0, MEMORY);
         instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
         return DECODE_success;
 
-    case 0xB7: /* movz m16/m32, r32/r64 */
-        instr->instr = INSTR_MOVZ;
+    case 0xB7: /* movzx m16/m32, r32/r64 */
+        instr->instr = INSTR_MOVZX;
+        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         index = get_index(opcode + 1, rex);
-        if (rex & 0x8) {
-            instr->op_size = LONG;
-            instr->operand[1] = mk_operand(QUAD, index, 0, REGISTER);
-        } else {
-            instr->op_size = WORD;
-            instr->operand[1] = mk_operand(LONG, index, 0, REGISTER);
-        }
-        instr->operand[0] = mk_operand(instr->op_size, 0, 0, MEMORY);
+        if (rex & 0x8)
+            instr->operand[0] = mk_operand(LONG, 0, 0, MEMORY);
+        else
+            instr->operand[0] = mk_operand(WORD, 0, 0, MEMORY);
+        instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
+        return DECODE_success;
+
+    case 0xBE: /* movsx m8, r16/r32/r64 */
+        instr->instr = INSTR_MOVSX;
+        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+        index = get_index(opcode + 1, rex);
+        instr->operand[0] = mk_operand(BYTE, 0, 0, MEMORY);
+        instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
+        return DECODE_success;
+
+    case 0xBF: /* movsx m16, r32/r64 */
+        instr->instr = INSTR_MOVSX;
+        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+        index = get_index(opcode + 1, rex);
+        instr->operand[0] = mk_operand(WORD, 0, 0, MEMORY);
+        instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
         return DECODE_success;
 
     case 0xA3: /* bt r32, m32 */
@@ -702,7 +716,7 @@ static void mmio_operands(int type, unsigned long gpa, struct instruction *inst,
         send_mmio_req(type, gpa, 1, inst->op_size, value, IOREQ_WRITE, 0);
     } else if (inst->operand[0] & MEMORY) { /* dest is register */
         /* send the request and wait for the value */
-        if (inst->instr == INSTR_MOVZ)
+        if ( (inst->instr == INSTR_MOVZX) || (inst->instr == INSTR_MOVSX) )
             send_mmio_req(type, gpa, 1, size_reg, 0, IOREQ_READ, 0);
         else
             send_mmio_req(type, gpa, 1, inst->op_size, 0, IOREQ_READ, 0);
@@ -827,7 +841,8 @@ void handle_mmio(unsigned long va, unsigned long gpa)
         break;
     }
 
-    case INSTR_MOVZ:
+    case INSTR_MOVZX:
+    case INSTR_MOVSX:
         mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mmio_opp, regs);
         break;
 
index eb637bf80b59121d4d3af9c724286275164503ae..96c8f9c56c0ad5e7b491641e4f96aae4ae13e2c8 100644 (file)
@@ -567,7 +567,9 @@ static unsigned long vlapic_read(struct vcpu *v, unsigned long address,
 
     if ( len != 4) {
         /* some bugs on kernel cause read this with byte*/
-        printk("Local APIC read with len = %lx, should be 4 instead\n", len);
+        VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
+                    "Local APIC read with len = %lx, should be 4 instead\n",
+                    len);
     }
 
     alignment = offset & 0x3;
index ad71bc5b9f08d7058e7ade94436b4ed68871f5f4..3e7563fe5c08d15bbfcb263e15bc6547676947c9 100644 (file)
 #define REPNZ   0x2
 #define OVERLAP 0x4
 
-#define INSTR_PIO 1
-#define INSTR_OR 2
-#define INSTR_AND 3
-#define INSTR_XOR 4
-#define INSTR_CMP 5
-#define INSTR_MOV 6
-#define INSTR_MOVS 7
-#define INSTR_MOVZ 8
-#define INSTR_STOS 9
-#define INSTR_TEST 10
-#define INSTR_BT 11
+#define INSTR_PIO   1
+#define INSTR_OR    2
+#define INSTR_AND   3
+#define INSTR_XOR   4
+#define INSTR_CMP   5
+#define INSTR_MOV   6
+#define INSTR_MOVS  7
+#define INSTR_MOVZX 8
+#define INSTR_MOVSX 9
+#define INSTR_STOS  10
+#define INSTR_TEST  11
+#define INSTR_BT    12
 
 struct instruction {
     __s8    instr; /* instruction type */